#ifndef DATA_CONTROL_H
#define DATA_CONTROL_H

#include <mutex>
#include <condition_variable>
#include <vector>
#include <list>
#include <atomic>
#include <shared_mutex>
#include <map>
#include <utility>
#include <algorithm>
#include <numeric>
#include <thread>
#include <oatpp/core/macro/component.hpp>
#include "Timer.hpp"
#include "databaseControl.hpp"
#include "DynamicStruct.hpp"
#include "systemInfo.hpp"
#include <string>
#include <unordered_map>
#include <nlohmann/json.hpp>

class DataBuffer
{
    private:
        std::shared_mutex MapRWLock;   //读写锁
        // DeviceID, Receive Data
        std::map<int32_t,std::list<DynamicStruct>>* ptrDataBuffer;
    public:
        DataBuffer();
        ~DataBuffer();
        std::vector<std::pair<int32_t,DynamicStruct>> avgSwapBuffer();  //获取旧列表，添加新列表
        std::vector<int32_t> getDeviceItems();  //获取设备列表 （上锁）
        void addData(int32_t DeviceID,DynamicStruct Value);  //添加数据 (新设备上大锁，新数据上小锁)
        bool getDeviceData(int32_t DeviceID,DynamicStruct& lastData);   //获取设备信息（内部接口）
};

struct DeviceInfo  //定义一个设备的信息
{
    int32_t DeviceID;
    int32_t DeviceType;
    std::string TypeName;
    std::string DeviceName;
};

class DataControl
{
    public:
        DataControl();
        ~DataControl();
        void addType0Data(int32_t DeviceID,double Value);  //类型0数据接口
        void addType2Data(int32_t DeviceID,double valueCPU,double valueMEM); //类型2数据接口

        std::string getLastTimeValue(double RequestData);   //获取最后一次更新数据，返回数据格式为JSON
        std::string getDeviceList();  //获取设备列表
        std::string getHistoryData(int32_t DeviceID,int32_t timeLength);  //获取历史数据

        std::string getServerInfo(); //获取服务器的信息，这里指不怎么会变化的，就一次获取
        std::string getServerStatus(); //获取设备的CPU,内存,磁盘信息
    private:
        SimpleTimer timer; //定时器
        DataBuffer dataBuffer;
        DatabaseControl DBcontrol;

        static SystemInfo systemInfo;  //这个设置为静态主要为了性能，防止在多个线程反复初始化

        static void TimerThread();
        static DataControl* currentClass;

        std::vector<std::string> getDeviceTypeField(int32_t DeviceID);
        //先DeviceIDMutex再DeviceTypeMutex ！！！
        static std::shared_mutex DeviceTypeMutex;
        static std::shared_mutex DeviceIDMutex;
        static std::map<int32_t,DeviceTypeItem> DeviceTypeMap;  //设备类型映射表
        static std::map<int32_t,DeviceIDItem> DeviceIDMap;  //设备信息映射表
};

#endif